#include <png.h>
#include <vector>

struct FilePiece
{
	size_t		len;
	unsigned char* data;
};

std::vector<FilePiece> filePieces;

void pngwritefunc(png_structp png_ptr, png_bytep buffer, png_size_t size)
{
	FilePiece fp;
	fp.len = size;
	fp.data = new unsigned char[size];
	memcpy(fp.data, buffer, size);
	filePieces.push_back(fp);
}

void pngflushfunc(png_structp png_ptr)
{
}

bool Sys_LightmapDataToImage(unsigned char* data, unsigned char** imageData, size_t* imageSize)
{
	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL)
	{
		return false;
	}

	png_set_compression_level(png_ptr, 0);

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		png_destroy_write_struct(&png_ptr, NULL);
		return false;
	}

	png_set_write_fn(png_ptr, data, pngwritefunc, pngflushfunc);

	png_set_IHDR(png_ptr, info_ptr, 128, 128, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
		PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	png_bytep rows[128];
	for (int i = 0; i < 128; i++)
	{
		rows[127 - i] = (png_bytep)(data + (i * 128 * 3));
	}
	png_set_rows(png_ptr, info_ptr, &rows[0]); 

	png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
	
	*imageSize = 0;
	for (size_t i = 0; i < filePieces.size(); i++)
	{
		FilePiece& fp = filePieces.at(i);
		*imageSize += fp.len;
	}

	int bufferPos = 0;
	*imageData = new unsigned char[*imageSize];
	for (size_t i = 0; i < filePieces.size(); i++)
	{
		FilePiece& fp = filePieces.at(i);
		memcpy((*imageData) + bufferPos, fp.data, fp.len);
		bufferPos += fp.len;
	}

	png_destroy_write_struct(&png_ptr, &info_ptr);
	filePieces.clear();

	return true;
}